2022년 12월 20일
fastAPI란 파이썬 버전 3.6버전 이상부터 사용가능한 타입힌트를 바탕으로 쉽고 빠르게, 성능이 좋은 API서버를 개발할 수 있는 훌륭한 오픈소스 프레임워크입니다.
아래에서 세부사항에 대해 조금씩 공부해보며, fastAPI에 장점을 배워보겠습니다.
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel # 베이스모델
class User(BaseModel):
id: int # 타입어노테이션만 할 경우 해당 필드는 required 하다는 것을 알려줍니다.
name = '홍길동' # 아무것도 들어오지 않을경우 기본값이며, str을 추론합니다.
date_joined: Optional[datetime] = None
friends: List[int] = []
data = {
'id': '1',
'date_joined': '2021-12-08 10:02',
'friends': [2, 3, '4']
}
user = User(**data)
print(user.id) # 1
print(user.date_joined) # datetime.datetime(2019, 6, 1, 12, 22)
print(friends) # 2, 3, 4
보통 DRF Serializer와 많이 비교되는것으로 알고있습니다. 이런 DRF Serializer와 pydantic의 차이점은 pydantic의 파싱 라이브러리라는 점입니다.
위를 보면 아시겠지만, id의 타입을 int로 했음에도 불구하고, str값을 넣어주었을때 에러가 나지않고 파싱되어 int로 출력되는것을 볼수 있습니다.
파싱할수 있는 데이터가 들어오면 어노테이션한 타입으로 파싱해주며, 그것이 아니라면 에러를 출력합니다.
평균적으로 DRF Serializer 보다는 pydantic이 더 빠르다고 합니다.
다만 pydantic의 경우 Validation이 가능하지만 Serializer와는 약간 결이 다르다고 하니 Serializer에서 어떤 기능을 사용하는지 파악 후에, pydantic을 사용해야 할 것 같습니다
# main.py
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def hello():
return "Hello, World!"
if __name__ == "__main__":
uvicorn.run("main:app", reload=True)
장고를 사용해보지 않아서 모르지만, 실제로 ‘hello world’를 받을때까지 2분도 걸리지 않았습니다.
가상환경을 만들고 fastApi를 설치하고 uvicorn을 설치한 뒤 fastAPI를 불러서 간단하게 helloWold를 화면에 출력해볼수 있었습니다.
해당 내용은 다른 python 프레임워크를 사용해봐야 체감할 수 있겠지만, 장고 튜토리얼만 살짝봐도 fastAPI 가 더 간결하다는것을 쉽게 느낄수 있었습니다.
@app.get("/user")
async def root():
return {"user" : "covy"}
user의 정보를 받기위해 다음과 같은 API를 개발했다고 생각해봅시다.
일반적으로 Swagger같은 툴로 API의 테스트 겸 문서화를 많이들 한다고 합니다.
그런 Swagger를 fastAPI에서는 자동으로 생성해줍니다.
포트번호 뒤에 /docs를 입력해주면..
위와 같이 자동으로 Swagger가 생성되며 아래처럼 똑같이 사용 할 수 있습니다.
fastAPI 개발자는 fastAPI 의 성능이 node.js 보다 빠르고 go와 비교될 정도로 빠른 속도를 자랑한다고 합니다.
그렇다면 fastAPI는 어떻게 이런 빠른속도를 가질 수 있는것일까요?
이에대한 답으로 개발자 Sebastián Ramírez 는 다음과 같이 답했습니다.
Why is FastAPI fast?
It's built on top of Starlette, normally run with Uvicorn,
that uses Uvloop, a high-performance drop-in replacement for asyncio
(it powers all the async/await stuff).
And Uvloop and Pydantic are both built with Cython. A sort-of compiled Python. 🚅
요약하면 fastAPI는 Starlette기반으로 만들어졌는데,Starlette는 Uvicorn을 써서 빠르고, Uvicorn은 Uvloop를 사용해서 빠르고, Uvloop은 Cython을 기반으로 만들어져 빠르다는 것입니다.
간략하게 알아봅시다.
Starlette의 설명 문구인 ‘The little ASGI framework that shines’ 와 같이 Starlette은 ASGI 웹 서버인 Uvicorn 위에서 실행되는 프레임워크입니다.
fastAPI가 Starlette를 기반으로 개발되었기 때문에 Starlette를 직접 사용하는것보다는 조금 성능이 떨어질 수 있지만, fastAP의 장점과 Starlette의 장점이 더해져서 더 막강한 프레임워크라고 할 수 있습니다.
Starlette도 가장 중요한 포인트는 Uvicorn을 사용한다는 점입니다. 물론 이는 fastAPI에서도 가장 중요한 핵심입니다.
Uvicorn(ASGI Web Server)은 uvloop 및 httptools를 사용하는 ASGI web server입니다.
그렇다면 ASGI란 무엇일까요?
ASGI(Asynchronous Server Gateway Interface)는 비동기 Python 웹 서버입니다.
즉 비동기 서버 게이트웨이 인터페이스인데, ASGI덕분에 비동기 처리를 할 수 있나봅니다. 그러다보니 당연한 의문이 생깁니다. 파이썬은 비동기처리가 안되나? 그리고 ASGI가 있다면 반대개념도 있을까?
맞습니다 장고와 플라스크는 WSGI(Web Server Gateway Interface)를 이용한다고 합니다.
클라이언트에서 동적인 요청을 보내면 웹서버는 웹 어플리케이션에게 요청을 위임하고 요청한 위임에 대한 결과를 받습니다. 그런데 웹서버가 웹 어플리케이션과 대화하려면 중간에 인터페이스가 필요합니다.
CGI,WAS(ex.톰캣)같은 것이 있으나 파이썬에서는 WSGI를 사용합니다. WSGI의 대표적인 예시로는 장고에서 사용중인 Gunicorn이 있습니다.
다만 WSGI는 요청에 대한 콜백이 동기적인 형태를 가졌습니다. 이는 파이썬자체가 동기적인 방식으로 동작하는 언어이기 때문에 WSGI또한 함께 가지는 문제점입니다.
(물론 셀러리와 비동기 큐를 이용하면 비동기처리를 할 수는 있습니다.)
이러한 문제점을 해결하기 위해 ASGI가 나오게 되었으며, 훌륭하게 비동기 처리를 할 수 있게 되었습니다.
이런 비동기처리는 파이썬의 asyncio와 코루틴에 대한 지식이 있다면 더 쉽게 이해 할수 있을것입니다.
또한 Uvicorn은 동시성을 기반으로 싱글 프로세스로 동작하는데, 병렬처리를 헤야할 필요가 있다면 Gunicorn을 통해 추가적인 프로세스를 실행해 병렬성을 확보할 수 있습니다.
이때 Gunicorn은 Uvicorn을 관리하며 여러 프로세스를 실행시킬수 있습니다.
uvloop는 asyncio를 대체하기 위해 만들어졌습니다. Uvloop는 Cython으로 작성되었으며 libuv 위에 구축되었습니다.
참고로 libuv는 nodejs에서 사용하는 고성능 다중 플랫폼 비동기 I / O 라이브러리입니다 해당 라이브러리에 대해 제대로 알기 위해서는 더 깊은 지식이 필요하니 일단 비동기 입출력, 이벤트 기반에 초점을 맞춘 라이브러리라고 인지하겠습니다.
(nodejs v8엔진에서도 사용한다고 합니다.)
# pip로 설치해서 사용할수 있습니다.
pip install uvloop
import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
Cython은 파이썬 언어로 작성된 파일을 c/c++로 컴파일 해주는 컴파일언어라고 합니다. python 기반으로 C 루틴을 호출하기 때문에 컴퓨터 내에 c/c++이 설치되어 있어야 한다고 합니다.
파이썬을 컴파일해서 c로 실행시키는 만큼 빠른 속도를 가지고 있습니다.
즉 Cython을 기반으로 Uvloop를 개발하였으며, Uvloop와 httptools를 이용해서 ASGI를 구현한 Uvicorn위에서 실행되기 때문에 보다 빠른 성능을 가질수 있게 된것입니다.
요즘 정말 많은 블로그글들이 있고, 스택오버플로우며 어떤 기술에 대한 정보를 쉽게 알 수 있습니다. 다만 fastAPI는 장고나 플라스크와는 다르게 아직 커뮤니티가 많이 형성되지는 않았습니다.
하지만 첫 시작을 하려고 한다면 공식문서만 보아도 이해하는데에 충분한 도움을 줍니다.
상세하고 친절한 설명과 충분한 예제, 사진으로 이해도를 높여주며, 부분적이지만 한글로 번역된 점은 역시 처음 fastAPI를 배워가는 입장에서는 더 쉽게 다가갈 수 있었습니다.
무엇보다 훌륭한 공식문서는 가장 좋은 지름길이라고 생각합니다.
fastAPI를 짧게 배워보면서 쿼리변수를 알아서 넘겨준다던지, 스웨거를 자동으로 생성해준다던지, 몇 안되는 코드로 쉽고 빠르게 API를 만들어본 경험은 충분히 매력적이었습니다.
다만, 다른 프레임워크(특히 플라스크와 주로 비교가된다고 합니다)와 서버개발의 경험이 없기때문에 fastAPI가 다른것과 비교해서 이것이 강점이다! 라고 느끼기에는 다소 무리가 있었습니다.
다음번에는 장고를 배워보며 fastAPI에서 했던것과 비교해보겠습니다.